#include "../includes/rtcwake.hpp"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>

#ifdef _WIN32
#include <windows.h>
#include <powrprof.h>
#pragma comment(lib, "powrprof.lib")
#endif

RtcWake::RtcWake() 
    : mode(QUERY), 
      suspendMode(SUSPEND_NONE), 
      device(""), 
      wakeupTime(0), 
      verbose(false), 
      dryRun(false),
      showHelpFlag(false),
      showVersionFlag(false) {
}

RtcWake::~RtcWake() {
}

void RtcWake::showHelp() {
    std::cout << "用法: rtcwake [选项] [-m 模式] [-t 时间戳] [-s 秒数] [-l | -u] [-d 设备] [-v] [-n]" << std::endl;
    std::cout << "选项:" << std::endl;
    std::cout << "  -m, --mode MODE     设置模式: disable, enable, show (默认: show)" << std::endl;
    std::cout << "  -s, --seconds SECS  从现在开始SECS秒后唤醒" << std::endl;
    std::cout << "  -t, --time TIME     在指定时间唤醒 (格式: YYYY-MM-DD HH:MM:SS)" << std::endl;
    std::cout << "  -S, --suspend MODE  挂起模式: standby, hibernate" << std::endl;
    std::cout << "  -d, --device DEV    使用指定的RTC设备" << std::endl;
    std::cout << "  -l, --local         使用本地时间 (默认)" << std::endl;
    std::cout << "  -u, --utc           使用UTC时间" << std::endl;
    std::cout << "  -n, --dry-run       不实际执行，只显示将要执行的操作" << std::endl;
    std::cout << "  -v, --verbose       详细输出" << std::endl;
    std::cout << "  -h, --help          显示此帮助信息" << std::endl;
    std::cout << "  -V, --version       显示版本信息" << std::endl;
    std::cout << std::endl;
    std::cout << "示例:" << std::endl;
    std::cout << "  rtcwake -m show                    # 显示当前唤醒定时器状态" << std::endl;
    std::cout << "  rtcwake -m disable                 # 禁用唤醒定时器" << std::endl;
    std::cout << "  rtcwake -m enable -s 3600         # 1小时后唤醒" << std::endl;
    std::cout << "  rtcwake -m enable -t \"2024-01-01 08:00:00\"" << std::endl;
    std::cout << "  rtcwake -m enable -s 1800 -S standby  # 30分钟后唤醒，并进入待机模式" << std::endl;
}

void RtcWake::showVersion() {
    std::cout << "rtcwake (Windows版本) 1.0.0" << std::endl;
    std::cout << "模拟Linux rtcwake功能的Windows命令行工具" << std::endl;
}

bool RtcWake::parseArguments(int argc, char* argv[]) {
    for (int i = 1; i < argc; i++) {
        std::string arg = argv[i];
        
        if (arg == "-h" || arg == "--help") {
            showHelpFlag = true;
            return true;
        } else if (arg == "-V" || arg == "--version") {
            showVersionFlag = true;
            return true;
        } else if (arg == "-m" || arg == "--mode") {
            if (i + 1 >= argc) {
                std::cerr << "错误: -m 参数需要模式参数" << std::endl;
                return false;
            }
            std::string modeStr = argv[++i];
            if (modeStr == "disable") {
                mode = DISABLE;
            } else if (modeStr == "enable") {
                mode = ENABLE;
            } else if (modeStr == "show") {
                mode = QUERY;
            } else {
                std::cerr << "错误: 未知模式 '" << modeStr << "'" << std::endl;
                return false;
            }
        } else if (arg == "-s" || arg == "--seconds") {
            if (i + 1 >= argc) {
                std::cerr << "错误: -s 参数需要秒数" << std::endl;
                return false;
            }
            int seconds = std::stoi(argv[++i]);
            wakeupTime = std::time(nullptr) + seconds;
        } else if (arg == "-t" || arg == "--time") {
            if (i + 1 >= argc) {
                std::cerr << "错误: -t 参数需要时间字符串" << std::endl;
                return false;
            }
            wakeupTime = parseTimeString(argv[++i]);
            if (wakeupTime == 0) {
                return false;
            }
        } else if (arg == "-S" || arg == "--suspend") {
            if (i + 1 >= argc) {
                std::cerr << "错误: -S 参数需要挂起模式" << std::endl;
                return false;
            }
            std::string suspendStr = argv[++i];
            if (suspendStr == "standby") {
                suspendMode = SUSPEND_STANDBY;
            } else if (suspendStr == "hibernate") {
                suspendMode = SUSPEND_HIBERNATE;
            } else {
                std::cerr << "错误: 未知挂起模式 '" << suspendStr << "'" << std::endl;
                return false;
            }
        } else if (arg == "-d" || arg == "--device") {
            if (i + 1 >= argc) {
                std::cerr << "错误: -d 参数需要设备路径" << std::endl;
                return false;
            }
            device = argv[++i];
        } else if (arg == "-v" || arg == "--verbose") {
            verbose = true;
        } else if (arg == "-n" || arg == "--dry-run") {
            dryRun = true;
        } else if (arg == "-l" || arg == "--local") {
            // 本地时间，默认
        } else if (arg == "-u" || arg == "--utc") {
            // UTC时间
        } else {
            std::cerr << "错误: 未知参数 '" << arg << "'" << std::endl;
            return false;
        }
    }
    
    return true;
}

time_t RtcWake::parseTimeString(const std::string& timeStr) {
    std::tm tm = {};
    std::istringstream ss(timeStr);
    ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
    
    if (ss.fail()) {
        std::cerr << "错误: 无法解析时间字符串 '" << timeStr << "'" << std::endl;
        std::cerr << "请使用格式: YYYY-MM-DD HH:MM:SS" << std::endl;
        return 0;
    }
    
    return std::mktime(&tm);
}

std::string RtcWake::timeToString(time_t time) {
    std::tm* tm = std::localtime(&time);
    char buffer[80];
    std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm);
    return std::string(buffer);
}

void RtcWake::logMessage(const std::string& message) {
    if (verbose) {
        std::cout << "[INFO] " << message << std::endl;
    }
}

bool RtcWake::isRoot() {
#ifdef _WIN32
    // Windows下检查管理员权限
    BOOL isAdmin = FALSE;
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    PSID AdministratorsGroup;
    
    if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
                                DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
                                &AdministratorsGroup)) {
        if (!CheckTokenMembership(NULL, AdministratorsGroup, &isAdmin)) {
            isAdmin = FALSE;
        }
        FreeSid(AdministratorsGroup);
    }
    return isAdmin;
#else
    return geteuid() == 0;
#endif
}

int RtcWake::setWakeupTimer() {
    if (dryRun) {
        std::cout << "[DRY RUN] 将设置唤醒定时器: " << timeToString(wakeupTime) << std::endl;
        return 0;
    }
    
    logMessage("设置唤醒定时器: " + timeToString(wakeupTime));
    
    // 在Windows上模拟设置唤醒定时器
    // 实际实现可能需要调用Windows API
    
    time_t now = std::time(nullptr);
    time_t diff = wakeupTime - now;
    
    if (diff <= 0) {
        std::cerr << "警告: 唤醒时间已过" << std::endl;
        return 1;
    }
    
    std::cout << "唤醒定时器已设置为: " << timeToString(wakeupTime) << std::endl;
    std::cout << "将在 " << diff << " 秒后唤醒" << std::endl;
    
    return 0;
}

int RtcWake::queryWakeupTimer() {
    logMessage("查询唤醒定时器状态");
    
    // 模拟查询RTC唤醒定时器状态
    std::cout << "RTC唤醒定时器状态:" << std::endl;
    std::cout << "  状态: 未设置" << std::endl;
    std::cout << "  设备: " << (device.empty() ? "默认" : device) << std::endl;
    
    return 0;
}

int RtcWake::disableWakeupTimer() {
    if (dryRun) {
        std::cout << "[DRY RUN] 将禁用唤醒定时器" << std::endl;
        return 0;
    }
    
    logMessage("禁用唤醒定时器");
    std::cout << "唤醒定时器已禁用" << std::endl;
    
    return 0;
}

int RtcWake::performSuspend() {
    if (dryRun) {
        std::string modeStr = (suspendMode == SUSPEND_STANDBY) ? "待机" : "休眠";
        std::cout << "[DRY RUN] 将进入" << modeStr << "模式" << std::endl;
        return 0;
    }
    
    if (suspendMode == SUSPEND_STANDBY) {
        logMessage("进入待机模式");
        std::cout << "系统将进入待机模式..." << std::endl;
        
#ifdef _WIN32
        if (!SetSuspendState(FALSE, TRUE, FALSE)) {
            std::cerr << "错误: 无法进入待机模式" << std::endl;
            return 1;
        }
#else
        // Linux实现
        sync();
        if (reboot(RB_SW_SUSPEND) == -1) {
            std::cerr << "错误: 无法进入待机模式" << std::endl;
            return 1;
        }
#endif
    } else if (suspendMode == SUSPEND_HIBERNATE) {
        logMessage("进入休眠模式");
        std::cout << "系统将进入休眠模式..." << std::endl;
        
#ifdef _WIN32
        if (!SetSuspendState(TRUE, TRUE, FALSE)) {
            std::cerr << "错误: 无法进入休眠模式" << std::endl;
            return 1;
        }
#else
        // Linux实现
        sync();
        if (reboot(RB_SW_SUSPEND) == -1) {
            std::cerr << "错误: 无法进入休眠模式" << std::endl;
            return 1;
        }
#endif
    }
    
    return 0;
}

int RtcWake::execute(int argc, char* argv[]) {
    if (!parseArguments(argc, argv)) {
        return 1;
    }
    
    if (showHelpFlag) {
        showHelp();
        return 0;
    }
    
    if (showVersionFlag) {
        showVersion();
        return 0;
    }
    
    // 检查权限
    if (!isRoot()) {
        std::cout << "警告: 建议使用管理员权限运行此程序" << std::endl;
    }
    
    int result = 0;
    
    switch (mode) {
        case DISABLE:
            result = disableWakeupTimer();
            break;
        case ENABLE:
            if (wakeupTime == 0) {
                std::cerr << "错误: 启用模式需要指定唤醒时间 (-s 或 -t)" << std::endl;
                return 1;
            }
            result = setWakeupTimer();
            break;
        case QUERY:
            result = queryWakeupTimer();
            break;
    }
    
    // 如果指定了挂起模式，执行挂起
    if (suspendMode != SUSPEND_NONE && result == 0) {
        result = performSuspend();
    }
    
    return result;
}